iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0

Apache POI匯出Excel的方法相較於JasperReports沒有那麼直觀,沒有GUI介面可以使用,因此Excel中哪一格要顯示什麼值,都要靠單元格的座標(第幾行、第幾列),需要想像一下報表的布局。

Excel相關介面

Apache POI中,可以由下列的介面來操作Excel。

  • Workbook: 為Excel工作簿,由HSSFWorkbook、XSSFWorkbook和SXSSFWorkbook實現的一個介面。
  • Sheet: 為Excel工作薄中的一個試算表,Sheet介面繼承了Iterable,可以直接遍歷試算表下面的列。
  • Row: 為試算表中的列。Row介面繼承了Iterable,可以直接遍歷每列的單元格。
  • Cell: 為試算表中的單元格。

因此將資料寫入Excel的時候,要知道第幾行、第幾列,以及要寫入什麼資料。

情境:匯出學生成績資料表

直接由一個範例來看看如何利用這些介面寫入資料。

查詢資料

第一步先查詢要匯出的資料,資料放在StudentCourseScoreReportModel物件中。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentCourseScoreReportModel {
    private String studentNumber;

    private String fullName;

    private String grade;

    private String courseDesc;

    private String departmentDesc;

    private Integer score;

    private String testDate;
}
// 查詢學生考試成績資料資料
List<StudentCourseScoreReportModel> studentCourseScoreReportModelList = reportDemoService.getStudentCourseScoreData();

準備欄位名稱資料

如果有固定的欄位名稱要顯示,我會先放在一個陣列中。

// 欄位名稱
String[] columnNames = {"學號", "科系", "年級", "姓名", "課程", "成績", "考試日期"};

建立Excel相關物件,放入資料

大致上的步驟如下,第幾步可以對應註解來看:

  1. 建立Workbook
    • 資料量不大的情況下,我建立XSSFWorkbook就足夠了,記得使用完後要用close()方法釋放資源。Workbook的實現類別,有實作AutoCloseable介面,因此可以用try-with-resources自動關閉
  2. 建立Sheet
    • createSheet()方法建立工作簿中的試算表,參數為試算表名稱
  3. 建立Row
    • createRow()方法建立試算表中的列,參數就是列數,但是 第一列是從0開始
  4. 建立Cell
    • createCell()方法建立列中的單元格,參數是行數,一樣 第一(直)行是從0開始
    • 我想在第一行第一列設定標題,因此我createRow()createCell()的參數都先設為0,以setCellValue()方法設定單元格的值
  5. 第2列作為欄位名稱,可以將前面設定好的columnNames資料放入cell
  6. 以for loop遍歷列的資料
    • 我的資料studentCourseScoreReportModelList是一列一列往下長的,因此先以for loop遍歷資料
    • 在第4、5步我已經將第1、2列設定成標題與欄位名稱了,所以資料要從第3列開始
  7. 以for loop遍歷行的資料
    • 我用switch case設定第幾行放入StudentCourseScoreReportModel中哪個屬性的資料
  8. write()方法將ByteArrayOutputStream寫入工作簿,就完成啦
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
     // 1.建立Workbook
     Workbook workbook = new XSSFWorkbook();) {
    // 2.建立excel sheet(參數為sheetname)
    Sheet sheet = workbook.createSheet("學生考試成績表");

    // 3.建立列物件(參數為列數,從0開始)
    Row titleRow = sheet.createRow(0);
    // 4.建立此列的單元格物件
    Cell titleCell = titleRow.createCell(0);
    // 設定cell的內容
    titleCell.setCellValue("XX大學 學生考試成績表");

    // 5.第2列作為欄位名稱
    Row columnTitleRow = sheet.createRow(1);
    for (int k = 0; k < columnNames.length; k++) {
        Cell contentCell = columnTitleRow.createCell(k);
        contentCell.setCellValue(columnNames[k]);
    }

    // 6.遍歷列的資料
    for (int i = 0; i < studentCourseScoreReportModelList .size(); i++) {
        StudentCourseScoreReportModel model = studentCourseScoreReportModelList .get(i);

        // i+2因為第1列是標題,第2列是欄位名稱
        Row contentRow = sheet.createRow(i + 2);
        // 7.行的資料
        for (int j = 0; j < columnNames.length; j++) {
            Cell contentCell = contentRow.createCell(j);
            switch (j) {
                case 0:
                    contentCell.setCellValue(model.getStudentNumber());
                    break;
                case 1:
                    contentCell.setCellValue(model.getDepartmentDesc());
                    break;
                case 2:
                    contentCell.setCellValue(model.getGrade());
                    break;
                case 3:
                    contentCell.setCellValue(model.getFullName());
                    break;
                case 4:
                    contentCell.setCellValue(model.getCourseDesc());
                    break;
                case 5:
                    contentCell.setCellValue(model.getScore());
                    break;
                case 6:
                    contentCell.setCellValue(model.getTestDate());
                    break;
            }
        }
    }

    // 8.寫入ByteArrayOutputStream 匯出Excel
    workbook.write(bos);
} catch (Exception e) {
    // 寫入失敗
    throw new RuntimeException(e);
}

匯出結果

結果就會如下圖

我自己在剛開始接觸Apache POI的時候是覺得以「匯出」這個功能來說,需要想一下才能設定,沒有Jaspersoft Studio直接有畫面來的直覺,如果要做有子報表的那種報表就會很複雜,比較適合較單純的報表匯出。不過Apache POI可以做到讀取Office文件,算是一大優勢。


Reference


上一篇
Apache POI-簡介
下一篇
Apache POI-SXSSFWorkbook到底有多快
系列文
Java工程師的報表入門與實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言